﻿using Hei.Captcha;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Qy.Core;
using Qy.Scenario;
using Qy.Web.Authorize;
using Qy.Web.Authorize.Common;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Qy.Web.Areas.Api;

[Route("Api/[controller]/[action]")]
public class LoginController : Base
{
    private readonly UserService _adminUserService;
    private readonly ApplicationContext _applicationContext;
    private readonly LogLoginService _logLoginService;
    private readonly ConfigService _configService;
    private readonly NoticeKeyService _noticeKey;
    private readonly ICacheManager _cacheManager;
    private readonly DictDataService _dictDataService;
    private readonly ConfigParmService _configParmService;
    private readonly MenuService _menuService;
    private readonly SecurityCodeHelper SecurityCodeHelper;
    public LoginController(ApplicationContext applicationContext,
        UserService adminUserService,
        LogLoginService logLoginService,
        ConfigService configService,
        NoticeKeyService noticeKey,
        ICacheManager cacheManager,
        DictDataService dictDataService,
        ConfigParmService configParmService,
        MenuService menuService,
        SecurityCodeHelper securityCodeHelper)
    {
        _applicationContext = applicationContext;
        _adminUserService = adminUserService;
        _logLoginService = logLoginService;
        _configService = configService;
        _noticeKey = noticeKey;
        _cacheManager = cacheManager;
        _dictDataService = dictDataService;
        _configParmService = configParmService;
        _menuService = menuService;
        SecurityCodeHelper = securityCodeHelper;
    }

    /// <summary>
    /// 图片验证码
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> CaptchaImage()
    {
        CacheConfig sytemConfig = await _configService?.GetByCacheConfigAsync();
        bool validCodeOn = sytemConfig.ValidCodeOn;
        if (sytemConfig.ValidCodeOn)
        {
            string uuid = Guid.NewGuid().ToString().Replace("-", "");
            int length = AppSettings.GetAppConfig("CaptchaOptions:length", 4);
            string code = SecurityCodeHelper.GetRandomEnDigitalText(length);
            int codeType = sytemConfig.ValidCodeType > 0 ? sytemConfig.ValidCodeType : 1;
            byte[] imgByte = codeType switch
            {
                1 => SecurityCodeHelper.GetGifEnDigitalCodeByte(code),
                2 => SecurityCodeHelper.GetGifBubbleCodeByte(code),
                3 => SecurityCodeHelper.GetEnDigitalCodeByte(code),
                _ => SecurityCodeHelper.GetBubbleCodeByte(code)
            };
            string base64Str = Convert.ToBase64String(imgByte);
            await _cacheManager.SetAsync(uuid, code, TimeSpan.FromSeconds(600));
            return Success(new { uuid, img = base64Str, validCodeOn });
        }
        else
            return Success(new { validCodeOn });
    }
    [HttpPost]
    [ModelStateFilter]
    public async Task<IActionResult> Login([FromBody] LoginDto dto)
    {
        CacheConfig sytemConfig = await _configService?.GetByCacheConfigAsync();
        if (sytemConfig.ValidCodeOn)
        {
            string cacheCode = await _cacheManager.GetAsync<string>(dto.Uuid);
            if (dto.ValidCode == null || cacheCode == null || !cacheCode.ToLower().Equals(dto.ValidCode.ToLower()))
            {
                return Fail("验证码错误！");
            }
        }

        User loginInfo = await _adminUserService.CheckUorP(dto);
        if (loginInfo == null)
            return Fail("用户名密码错误！");
        TokenModelJwt jwtSettings = new();
        AppSettings.Bind("Jwt", jwtSettings);
        jwtSettings.Expires = dto.Remember ? 60 * 30 : 30;
        jwtSettings.UserName = loginInfo.UserName;
        jwtSettings.UserId = loginInfo.Id;
        jwtSettings.UserGid = loginInfo.GroupId;
        string token = JwtHelper.CreateJwt(jwtSettings);
        string ip = HttpContext.GetClientUserIp();
        //更新数据库用户登录状态
        await _adminUserService.UpdateLoginInfoAsync(loginInfo.Id, ip);
        //登录日志单独写入
        await _logLoginService.InsertLogLoginAsync(loginInfo.Id, ip);
        return Success(new { token }, "登录成功！");
    }
    [Verify]
    [HttpGet]
    public async Task<IActionResult> GetUserInfo()
    {
        ILoginUserInfo userInfo = await _applicationContext.ILoginUserInfoMethods.LoginUserInfoAsync();
        SytemConfig sytemConfig = await _configService.GetSytemConfigAsync();
        ViewStatistics statistics = new()
        {
            NoticeNoRead = await _noticeKey.CountAsync(userInfo.UserId)//统计消息未读
        };
        List<ListViewDictData> listViewDictData = await _dictDataService.GetListAllAsync();
        List<ConfigParm> configParms = await _configParmService.GetListAllAsync();
        List<AsMenu> asMenus = await _menuService.GetUserMenu(userInfo, (int)MenuTypeEnum.Type.菜单);
        List<Menu> asMenuBottons = await _menuService.GetUserMenuBotton(userInfo, (int)MenuTypeEnum.Type.按钮);
        return Json(new { Status = 1, userInfo, sytemConfig, statistics, listViewDictData, configParms, asMenus, asMenuBottons });
    }
    /// <summary>
    /// 登出
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public IActionResult LoginOut()
    {
        _cacheManager.Remove(CacheConst.CACHE_KEY_USER_LOGIN + _applicationContext.ILoginUserInfoMethods.LoginUserId());
        return Success("成功退出,期待你再次回来！");
    }
}
